package com.ehsunbehravesh.utils;

import java.awt.Dimension;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Properties;
import java.util.Random;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import javax.swing.JDialog;
import javax.swing.JFrame;

public class Utils {

  public static String getRestOfStrings(String small, String big) {
    big = big.toLowerCase();
    small = small.toLowerCase();

    if (big.indexOf(small) == 0 && small.length() < big.length()) {
      return big.substring(small.length());
    }
    return "";
  }

  public static void openURL(String url) {
    if (!java.awt.Desktop.isDesktopSupported()) {
      return;
    }

    java.awt.Desktop desktop = java.awt.Desktop.getDesktop();

    if (!desktop.isSupported(java.awt.Desktop.Action.BROWSE)) {
      return;
    }

    try {
      java.net.URI uri = new java.net.URI(url);
      desktop.browse(uri);
    } catch (Exception e) {

      System.err.println(e.getMessage());
    }
  }

  public static String getFileExtension(File file) {
    String filename = file.getName().toLowerCase();
    return filename.substring(filename.lastIndexOf(".") + 1);
  }

  public static void setCenterOfScreen(JDialog dialog) {
    Dimension size = dialog.getSize();
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    Point position = new Point(screenSize.width / 2 - (size.width / 2), screenSize.height / 2 - (size.height / 2));
    dialog.setLocation(position);
  }

  public static void setCenterOfParent(JFrame parent, JDialog dialog) {
    Point parentPosition = parent.getLocation();
    Dimension parentSize = parent.getSize();
    Dimension size = dialog.getSize();
    Point position = new Point(parentPosition.x + (parentSize.width / 2 - size.width / 2), parentPosition.y + (parentSize.height / 2 - size.height / 2));
    dialog.setLocation(position);
  }

  public static void setCenterOfParent(JDialog parent, JDialog dialog) {
    Point parentPosition = parent.getLocation();
    Dimension parentSize = parent.getSize();
    Dimension size = dialog.getSize();
    Point position = new Point(parentPosition.x + (parentSize.width / 2 - size.width / 2), parentPosition.y + (parentSize.height / 2 - size.height / 2));
    dialog.setLocation(position);
  }

  public static String encrypt(String key, String text) throws UnsupportedEncodingException,
          NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
    byte[] byteKey = key.getBytes("UTF8");
    byte[] byteText = text.getBytes("UTF8");

    Cipher c = Cipher.getInstance("AES");
    SecretKeySpec k = new SecretKeySpec(byteKey, "AES");
    c.init(Cipher.ENCRYPT_MODE, k);
    byte[] byteEncrypted = c.doFinal(byteText);
    //BASE64Encoder encoder = new BASE64Encoder();
    //String encrypted = encoder.encode(byteEncrypted);
    String encrypted = new String(Base64Coder.encode(byteEncrypted));

    return encrypted;
  }

  public static byte[] encrypt(String key, byte[] byteText) throws UnsupportedEncodingException,
          NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
    byte[] byteKey = key.getBytes("UTF8");

    Cipher c = Cipher.getInstance("AES");
    SecretKeySpec k = new SecretKeySpec(byteKey, "AES");
    c.init(Cipher.ENCRYPT_MODE, k);
    byte[] byteEncrypted = c.doFinal(byteText);
    return byteEncrypted;
  }

  public static String decrypt(String key, String encrypted) throws UnsupportedEncodingException,
          NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
          BadPaddingException, IOException {
    byte[] byteKey = key.getBytes("UTF8");
    //BASE64Decoder decoder = new BASE64Decoder();
    //byte[] byteEncrypted = decoder.decodeBuffer(encrypted);
    byte[] byteEncrypted = Base64Coder.decode(encrypted);

    Cipher c = Cipher.getInstance("AES");
    SecretKeySpec k = new SecretKeySpec(byteKey, "AES");
    c.init(Cipher.DECRYPT_MODE, k);
    byte[] byteText = c.doFinal(byteEncrypted);
    String text = new String(byteText);

    return text;
  }

  public static byte[] decrypt(String key, byte[] byteEncrypted) throws UnsupportedEncodingException,
          NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
          BadPaddingException, IOException {
    byte[] byteKey = key.getBytes("UTF8");

    Cipher c = Cipher.getInstance("AES");
    SecretKeySpec k = new SecretKeySpec(byteKey, "AES");
    c.init(Cipher.DECRYPT_MODE, k);
    byte[] byteText = c.doFinal(byteEncrypted);

    return byteText;
  }

  public static void setClipboardContents(String aString, ClipboardOwner owner) {
    StringSelection stringSelection = new StringSelection(aString);
    Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
    clipboard.setContents(stringSelection, owner);
  }

  public static String getClipboardContents() {
    String result = "";
    Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
    //odd: the Object param of getContents is not currently used
    Transferable contents = clipboard.getContents(null);
    boolean hasTransferableText =
            (contents != null)
            && contents.isDataFlavorSupported(DataFlavor.stringFlavor);
    if (hasTransferableText) {
      try {
        result = (String) contents.getTransferData(DataFlavor.stringFlavor);
      } catch (UnsupportedFlavorException ex) {
        //highly unlikely since we are using a standard DataFlavor
        System.out.println(ex);
      } catch (IOException ex) {
        System.out.println(ex);
      }
    }
    return result;
  }

  public static String decryptGeneral1(String value) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException {
    String ekey = value.substring(5, 21);
    value = String.format("%s%s", value.substring(0, 5), value.substring(21));
    value = decrypt(ekey, value);
    return value;
  }

  public static String createEncryptionKey(String text) {
    String key = null;

    if (text.length() >= 8) {
      key = text.substring(0, 8);
      key = key + key;
    }

    return key;
  }

  private static String MD5(String message) throws NoSuchAlgorithmException {
    MessageDigest messageDigest = MessageDigest.getInstance("MD5");
    final byte[] data = message.getBytes(Charset.forName("UTF8"));
    final byte[] digest = messageDigest.digest(data);
    StringBuilder result = new StringBuilder();

    for (int i = 0; i < digest.length; i++) {
      byte b = digest[i];
      result.append(Integer.toHexString(0xFF & b));
    }

    return result.toString();
  }

  public static String SHA256(String message) throws NoSuchAlgorithmException {
    MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
    final byte[] data = message.getBytes(Charset.forName("UTF8"));
    final byte[] digest = messageDigest.digest(data);
    StringBuilder result = new StringBuilder();

    for (int i = 0; i < digest.length; i++) {
      byte b = digest[i];
      result.append(Integer.toHexString(0xFF & b));
    }

    return result.toString();
  }

  public static String getPathOfJar(boolean convertSpaces) {
    //return "/home/ehsun7b/code/mypasswords-home/sf/new/mypasswords7-svn/source/";
     String jarFilePath = new File(Utils.class.getProtectionDomain().getCodeSource().getLocation().getPath()).getAbsolutePath();
     jarFilePath = jarFilePath.substring(0, jarFilePath.lastIndexOf(getFileSeparator()) + 1);
     return convertSpaces ? jarFilePath.replaceAll("%20", "\\ ") : jarFilePath;
  }

  public static String getFileSeparator() {
    Properties sysProperties = System.getProperties();
    String fileSeparator = sysProperties.getProperty("file.separator");
    return fileSeparator;
  }

  public static int randomInt(int minimum, int maximum) {
    Random rn = new Random();
    /*
     int n = maximum - minimum + 1;
     int i = rn.nextInt() % n;
     return minimum + i;
     */
    int randomNumber = minimum + (int) (Math.random() * ((maximum - minimum) + 1));
    return randomNumber;
  }

  public static String randomString(int minLength, int maxLength) {
    String chars = "abcdefghijklmnopqrstuvwxyz";
    StringBuilder builder = new StringBuilder();
    int length = 0;
    if (minLength == maxLength) {
      length = minLength;
    } else {
      length = randomInt(minLength, maxLength);
    }

    for (int i = 0; i < length; i++) {
      boolean capital = randomInt(0, 1) == 1;
      int index = randomInt(0, chars.length() - 1);      
      char ch = chars.charAt(index);
      ch = capital ? Character.toUpperCase(ch) : ch;
      builder.append(ch);
    }

    return builder.toString();
  }  
}